/* global Cesium */

const Color = Cesium.Color;
const defaultValue = Cesium.defaultValue;
const defined = Cesium.defined;
const defineProperties = Object.defineProperties;
const Event = Cesium.Event;
const createPropertyDescriptor = Cesium.createPropertyDescriptor;
const Property = Cesium.Property;
const Material = Cesium.Material;

const defaultColor = Color.WHITE;

class DynamicRippleMaterialProperty {
    constructor(options = {}) {
        this._definitionChanged = new Event();
        this._color = undefined;
        this._colorSubscription = undefined;
        this._duration = 2000;
        this._time = new Date().getTime();
        this.duration = defaultValue(options.duration, 2);
        this.color = defaultValue(options.color, defaultColor);
    }
    /**
     * Gets the {@link Material} type at the provided time.
     *
     * @param {JulianDate} time The time for which to retrieve the type.
     * @returns {String} The type of material.
     */
    getType() {
        return Material.DynamicRippleType;
    }

    /**
     * Gets the value of the property at the provided time.
     *
     * @param {JulianDate} time The time for which to retrieve the value.
     * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned.
     * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied.
     */
    getValue(time, result) {
        if (!defined(result)) {
            result = {};
        }
        result.color = Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color);

        if (this._time === undefined) {
            this._time = time.secondsOfDay;
        }
        result.time = ((new Date().getTime() - this._time) % this._duration) / this._duration;
        // time.secondsOfDay - this._time;
        return result;
    }

    /**
     * Compares this property to the provided property and returns
     * <code>true</code> if they are equal, <code>false</code> otherwise.
     *
     * @param {Property} [other] The other property.
     * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise.
     */
    equals(other) {
        return (
            this === other || //
            (other instanceof DynamicRippleMaterialProperty && Property.equals(this._color, other._color))
        );
    }
}
defineProperties(DynamicRippleMaterialProperty.prototype, {
    duration: {
        get: function () {
            return this._duration / 1000;
        },
        set: function (value) {
            this._duration = value * 1000;
        },
    },
    /**
     * Gets a value indicating if this property is constant.  A property is considered
     * constant if getValue always returns the same result for the current definition.
     * @memberof PolylineGlowMaterialProperty.prototype
     * @type {Boolean}
     * @readonly
     */
    isConstant: {
        get: function () {
            return false;
        },
    },
    /**
     * Gets the event that is raised whenever the definition of this property changes.
     * The definition is considered to have changed if a call to getValue would return
     * a different result for the same time.
     * @memberof PolylineGlowMaterialProperty.prototype
     * @type {Event}
     * @readonly
     */
    definitionChanged: {
        get: function () {
            return this._definitionChanged;
        },
    },
    /**
     * Gets or sets the Property specifying the {@link Color} of the line.
     * @memberof PolylineGlowMaterialProperty.prototype
     * @type {Property}
     */
    color: createPropertyDescriptor('color'),
});

export default DynamicRippleMaterialProperty;
